<template>
    <view>
        <view v-if="isLoad === null" class="margin-top load notexist text-l text-darkgreen text-project"></view>
        <view v-if="isLoad === false" class="margin-top load loading text-l text-darkgreen text-project"></view>

        <block v-if="isLoad" v-for="(item, index) in fieldsClone" :key="index">
            <block v-if="item.type == 'line'">
                <view class="form-group">
                    <view :class="'title ' + (item.must ? 'must' : '')">{{ item.title }}:</view>
                    <input
                        :placeholder="item.desc || '请填写' + item.title"
                        placeholder-class="phc"
                        :maxlength="item.len"
                        @input="bindLineBlur"
                        :data-idx="index"
                        :value="item.val"
                    />
                </view>
                <view v-if="item.focus" class="hint-desc error">{{ item.focus }}</view>
            </block>

            <block v-else-if="item.type == 'number'">
                <view class="form-group">
                    <view :class="'title ' + (item.must ? 'must' : '')">{{ item.title }}:</view>
                    <input
                        type="number"
                        :placeholder="item.desc || '请填写' + item.title"
                        placeholder-class="phc"
                        :maxlength="item.len"
                        @input="bindLineBlur"
                        :data-idx="index"
                        :value="item.val"
                    />
                </view>
                <view v-if="item.focus" class="hint-desc error">{{ item.focus }}</view>
            </block>

            <block v-else-if="item.type == 'digit'">
                <view class="form-group">
                    <view :class="'title ' + (item.must ? 'must' : '')">{{ item.title }}:</view>
                    <input
                        type="digit"
                        :placeholder="item.desc || '请填写' + item.title"
                        placeholder-class="phc"
                        :maxlength="item.len"
                        @input="bindLineBlur"
                        :data-idx="index"
                        :value="item.val"
                    />
                </view>
                <view v-if="item.focus" class="hint-desc error">{{ item.focus }}</view>
            </block>

            <block v-else-if="item.type == 'select'">
                <view class="form-group">
                    <view :class="'title ' + (item.must ? 'must' : '')">{{ item.title }}</view>
                    <cmpt-picker :sourceData="item.selectOptions" :data-idx="index" @select="bindSelectCmpt($event, { idx: index })" :item="item.val" />
                </view>
                <view class="hint-desc" v-if="item.desc">{{ item.desc }}</view>
                <view v-if="item.focus" class="hint-desc error">{{ item.focus }}</view>
            </block>

            <block v-else-if="item.type == 'checkbox'">
                <view class="form-group">
                    <view class="action text-bold text-l">
                        <text class="text-red" v-if="item.must">*</text>
                        {{ item.title }}
                    </view>
                    <view class="action">至少选择{{ item.checkBoxLimit }}项</view>
                </view>
                <view class="form-group align-start" style="flex: 1; padding-left: 0; padding-right: 20rpx">
                    <cmpt-checkbox :sourceData="item.selectOptions" :data-idx="index" @select="bindCheckBoxCmpt($event, { idx: index })" :itemMulti="item.val" style="flex: 1" />
                </view>
                <view v-if="item.focus" class="hint-desc error">{{ item.focus }}</view>
            </block>

            <block v-else-if="item.type == 'date'">
                <view class="form-group arrow">
                    <view :class="'title ' + (item.must ? 'must' : '')">{{ item.title }}</view>
                    <picker class="picker-base" :data-idx="index" mode="date" @change="bindDayChange" :value="item.val">
                        <view class="picker-select">
                            {{ item.val || '年,月,日' }}
                        </view>
                    </picker>
                </view>
                <view class="hint-desc" v-if="item.desc">{{ item.desc }}</view>
                <view v-if="item.focus" class="hint-desc error">{{ item.focus }}</view>
            </block>

            <block v-else-if="item.type == 'year'">
                <view class="form-group arrow">
                    <view :class="'title ' + (item.must ? 'must' : '')">{{ item.title }}</view>
                    <picker class="picker-base" :data-idx="index" mode="date" fields="year" @change="bindDayChange" :value="item.val">
                        <view class="picker-select">
                            {{ item.val || '年份' }}
                        </view>
                    </picker>
                </view>
                <view class="hint-desc" v-if="item.desc">{{ item.desc }}</view>
                <view v-if="item.focus" class="hint-desc error">{{ item.focus }}</view>
            </block>

            <block v-else-if="item.type == 'month'">
                <view class="form-group arrow">
                    <view :class="'title ' + (item.must ? 'must' : '')">{{ item.title }}</view>
                    <picker class="picker-base" :data-idx="index" mode="date" fields="month" @change="bindDayChange" :value="item.val">
                        <view class="picker-select">
                            {{ item.val || '月份' }}
                        </view>
                    </picker>
                </view>
                <view class="hint-desc" v-if="item.desc">{{ item.desc }}</view>
                <view v-if="item.focus" class="hint-desc error">{{ item.focus }}</view>
            </block>

            <block v-else-if="item.type == 'hourminute'">
                <view class="form-group arrow">
                    <view :class="'title ' + (item.must ? 'must' : '')">{{ item.title }}</view>
                    <picker class="picker-base" :data-idx="index" mode="time" @change="bindDayChange" :value="item.val">
                        <view class="picker-select">
                            {{ item.val || '时间点' }}
                        </view>
                    </picker>
                </view>
                <view class="hint-desc" v-if="item.desc">{{ item.desc }}</view>
                <view v-if="item.focus" class="hint-desc error">{{ item.focus }}</view>
            </block>

            <block v-else-if="item.type == 'area'">
                <view class="form-group arrow">
                    <view :class="'title ' + (item.must ? 'must' : '')">{{ item.title }}</view>
                    <region-picker class="picker-base" :data-idx="index" @change="bindAreaChange($event, { idx: index })" :value="item.val">
                        <view v-if="item.val && item.val.length == 3" class="picker-select">
                            {{ item.val }}
                        </view>

                        <view v-else class="picker-select">省,区,市</view>
                    </region-picker>
                </view>
                <view class="hint-desc" v-if="item.desc">{{ item.desc }}</view>
                <view v-if="item.focus" class="hint-desc error">{{ item.focus }}</view>
            </block>

            <block v-else-if="item.type == 'switch'">
                <view class="form-group">
                    <view :class="'title ' + (item.must ? 'must' : '')">{{ item.title }}</view>
                    <switch v-if="item.val" @change="switchModel" :data-idx="index" class="green sm" :checked="true"></switch>
                    <switch v-else-if="!item.val" @change="switchModel" :data-idx="index" class="green sm"></switch>
                </view>
                <view class="hint-desc" v-if="item.desc">{{ item.desc }}</view>
                <view v-if="item.focus" class="hint-desc error">{{ item.focus }}</view>
            </block>

            <block v-else-if="item.type == 'multi'">
                <view class="form-group">
                    <view class="action text-bold text-l">
                        <text class="text-red" v-if="item.must">*</text>
                        {{ item.title }}
                    </view>
                    <view class="action">{{ item.val.length }}/200</view>
                </view>

                <view class="form-group align-start">
                    <textarea
                        @input="bindLineBlur"
                        :data-idx="index"
                        :value="item.val"
                        placeholder-class="phc"
                        :placeholder="item.desc || '请填写' + item.title"
                        style="min-height: 100rpx"
                        :auto-height="true"
                        :maxlength="item.len"
                    ></textarea>
                </view>
                <view v-if="item.focus" class="hint-desc error">{{ item.focus }}</view>
            </block>

            <block v-else-if="item.type == 'idcard'">
                <view class="form-group">
                    <view :class="'title ' + (item.must ? 'must' : '')">{{ item.title }}:</view>
                    <input
                        type="idcard"
                        :placeholder="item.desc || '请填写' + item.title"
                        placeholder-class="phc"
                        maxlength="18"
                        @input="bindLineBlur"
                        :data-idx="index"
                        :value="item.val"
                    />
                </view>
                <view v-if="item.focus" class="hint-desc error">{{ item.focus }}</view>
            </block>

            <block v-else-if="item.type == 'mobile' && item.mobileTruth">
                <view class="form-group">
                    <view :class="'title ' + (item.must ? 'must' : '')">{{ item.title }}:</view>
                    <text>{{ item.val || '未填写' }}</text>
                    <button open-type="getPhoneNumber" @getphonenumber="bindGetPhoneNumber" class="btn bg-blue bg-project light" :data-idx="index">
                        {{ item.val ? '一键修改手机号' : '一键填写手机号' }}
                    </button>
                </view>
                <view v-if="item.focus" class="hint-desc error">{{ item.focus }}</view>
            </block>

            <block v-else-if="item.type == 'mobile' && !item.mobileTruth">
                <view class="form-group">
                    <view :class="'title ' + (item.must ? 'must' : '')">{{ item.title }}:</view>
                    <input :placeholder="item.desc || '请填写' + item.title" placeholder-class="phc" maxlength="11" @input="bindLineBlur" :data-idx="index" :value="item.val" />
                </view>
                <view v-if="item.focus" class="hint-desc error">{{ item.focus }}</view>
            </block>
        </block>

        <cmpt-modal
            :show.sync="showCheckModal"
            type="longdialog"
            title="请核对填写的信息"
            @click="bindSubmitCmpt"
            class="modal-check-info"
            slot-class="slot-class"
            cancelText="返回修改"
            confirmText="确认提交"
        >
            <view class="item" v-for="(item, index) in formsClone" :key="index">
                <view class="title">{{ item.title }}：</view>

                <view class="content" v-if="item.val === true || item.val === false">{{ item.val ? '是' : '否' }}</view>

                <view class="content" v-else>{{ item.val }}</view>
            </view>
        </cmpt-modal>
    </view>
</template>

<script>
import cmptCheckbox from '@/cmpts/public/checkbox/checkbox_cmpt';
const pageHelper = require('../../../../helper/page_helper.js');
const cloudHelper = require('../../../../helper/cloud_helper.js');
const cacheHelper = require('../../../../helper/cache_helper.js');
const formSetHelper = require('../form_set_helper.js');
const validate = require('../../../../helper/validate.js');
const CACHE_FORM_SHOW_KEY = 'FORM_SHOW_CMPT';
const CACHE_FORM_SHOW_TIME = 31536000;
export default {
    components: {
        cmptCheckbox
    },
    data() {
        return {
            isLoad: false,
            showCheckModal: false,
            formsClone: '',
            fieldsClone: ''
        };
    },
    options: {
        addGlobalClass: true
    },
    /**
     * 组件的属性列表
     */
    props: {
        fields: {
            // 表单属性{mark,val,type,must,selectOptions,desc,title}
            type: Array,
            default: () => []
        },
        forms: {
            //表单值
            type: Array,
            default: () => [] // {mark,title,val,type}
        },
        isConfirm: {
            //是否显示核对信息modal
            type: Boolean,
            default: true
        },
        isCacheMatch: {
            //是否开启缓存匹配
            type: Boolean,
            default: true
        }
    },
    mounted() {
        // 处理小程序 attached 生命周期
        this.attached();
        // 处理小程序 ready 生命周期
        this.$nextTick(() => this.ready());
    },
    destroyed: function () {
        // 在组件实例被从页面节点树移除时执行
    },
    /**
     * 组件的方法列表
     */
    methods: {
        ready: function () {
            this.initFun();
        },

        attached: function () {},

        initFun: function () {
            let fields = this.fields;
            let newForms = [];
            for (let k in fields) {
                let node = {};
                node.mark = fields[k].mark;
                node.title = fields[k].title;
                node.type = fields[k].type;

                // 判断是否有表单值
                let val = this.getOneValFormFun(fields[k].mark, fields[k].title, fields[k].type);
                if (val === null) {
                    val = '';
                }

                // 类型修正
                val = this.fixTypeFun(fields[k].type, val);
                node.val = val;
                fields[k].val = val;
                newForms.push(node);
            }
            this.setData({
                formsClone: newForms,
                fieldsClone: fields,
                isLoad: true
            });
            //this.triggerEvent('forms', newForms);
        },

        // 根据mark和type获取上次值或者缓存值
        getOneValFormFun: function (mark, title, type) {
            let ret = null;

            // **** 对传入的默认值匹配
            let forms = this.forms;
            for (let k in forms) {
                if (forms[k].mark == mark) {
                    // 优先匹配mark
                    ret = forms[k].val;
                    break;
                }
                if (forms[k].title == title) {
                    // 再则匹配名称
                    ret = forms[k].val;
                    break;
                }
                if (type == 'mobile' && forms[k].type == 'mobile') {
                    ret = forms[k].val;
                    break;
                }
                if (type == 'idcard' && forms[k].type == 'idcard') {
                    ret = forms[k].val;
                    break;
                }
            }

            // **** 对缓存匹配
            let caches = cacheHelper.get(CACHE_FORM_SHOW_KEY);
            if (caches && Array.isArray(caches) && !ret) {
                for (let k in caches) {
                    if (caches[k].mark == mark) {
                        // 优先匹配mark
                        ret = caches[k].val;
                        break;
                    }
                    if (caches[k].title == title) {
                        // 再则匹配名称
                        ret = caches[k].val;
                        break;
                    }
                    if (type == 'mobile' && caches[k].type == 'mobile') {
                        ret = caches[k].val;
                        break;
                    }
                    if (type == 'idcard' && caches[k].type == 'idcard') {
                        ret = caches[k].val;
                        break;
                    }
                }
            }
            return ret;
        },

        // 原始form没有对应值, 给予默认值; 或者类型不对，修正
        fixTypeFun: function (type, val) {
            if (type != 'switch' && type != 'checkbox' && type != 'area') {
                if (typeof val === 'object' && !Array.isArray(val)) {
                    val = ''; // [object Object]需要转换
                } else {
                    val = String(val).trim();
                } // 前后去空格
            }

            // 原始form 有对应值，但是类型不正确
            switch (type) {
                case 'area': {
                    if (!Array.isArray(val) || val.length != 3) {
                        return '';
                    }
                    break;
                }
                case 'switch': {
                    if (typeof val != 'boolean') {
                        return true;
                    }
                    break;
                }
                case 'checkbox': {
                    if (!Array.isArray(val)) {
                        return [String(val).trim()];
                    } //尝试转为数组来匹配
                    break;
                }
                case 'year': {
                    if (!val || validate.checkYear(val)) {
                        return '';
                    }
                    break;
                }
                case 'month': {
                    if (!val || validate.checkYearMonth(val)) {
                        return '';
                    }
                    break;
                }
                case 'date': {
                    if (!val || validate.checkDate(val)) {
                        return '';
                    }
                    break;
                }
                case 'hourminute': {
                    if (!val || validate.checkHourMinute(val)) {
                        return '';
                    }
                    break;
                }
                case 'number': {
                    // 整数(字符形式)
                    if (!val || validate.checkInt(val)) {
                        return '';
                    }
                    break;
                }
                case 'digit': {
                    // 小数(字符形式)
                    if (!val || validate.checkDigit(val)) {
                        return '';
                    }
                    break;
                }
                default: {
                }
            }
            return val;
        },

        setFormFun: function (idx, val) {
            let forms = this.forms;
            let fields = this.fields;
            fields[idx].val = val;
            forms[idx].val = val;
            this.setData({
                formsClone: forms,
                fieldsClone: fields
            });

            //this.triggerEvent('forms', forms);
        },

        bindLineBlur: function (e) {
            let idx = pageHelper.dataset(e, 'idx');
            let val = e.detail.value.trim();
            this.setFormFun(idx, val);
        },

        bindDayChange: function (e) {
            let idx = pageHelper.dataset(e, 'idx');
            let val = e.detail.value.trim();
            this.setFormFun(idx, val);
        },

        bindAreaChange: function (e, _dataset) {
            /* ---处理dataset begin--- */
            this.handleDataset(e, _dataset);
            /* ---处理dataset end--- */
            let idx = pageHelper.dataset(e, 'idx');
            let val = e.detail.value;
            this.setFormFun(idx, val);
        },

        bindSelectCmpt: function (e, _dataset) {
            /* ---处理dataset begin--- */
            this.handleDataset(e, _dataset);
            /* ---处理dataset end--- */
            let idx = pageHelper.dataset(e, 'idx');
            let val = e.detail.trim();
            this.setFormFun(idx, val);
        },

        bindCheckBoxCmpt: function (e, _dataset) {
            /* ---处理dataset begin--- */
            this.handleDataset(e, _dataset);
            /* ---处理dataset end--- */
            let idx = pageHelper.dataset(e, 'idx');
            let val = e.detail;
            this.setFormFun(idx, val);
        },

        switchModel: function (e) {
            let idx = pageHelper.dataset(e, 'idx');
            let val = e.detail.value;
            this.setFormFun(idx, val);
        },

        bindGetPhoneNumber: async function (e) {
            if (e.detail.errMsg == 'getPhoneNumber:ok') {
                let cloudID = e.detail.cloudID;
                let params = {
                    cloudID
                };
                let opt = {
                    title: '手机验证中'
                };
                await cloudHelper.callCloudSumbit('passport/phone', params, opt).then((res) => {
                    let phone = res.data;
                    if (!phone || phone.length < 11) {
                        uni.showToast({
                            title: '手机号码获取失败，请重新绑定手机号码',
                            icon: 'none',
                            duration: 2000
                        });
                    } else {
                        let idx = pageHelper.dataset(e, 'idx');
                        this.setFormFun(idx, phone);
                    }
                });
            } else {
                uni.showToast({
                    title: '手机号码获取失败，请重新绑定手机号码',
                    icon: 'none'
                });
            }
        },

        checkForms: function () {
            // 写缓存
            if (this.isCacheMatch) {
                cacheHelper.set(CACHE_FORM_SHOW_KEY, this.forms, CACHE_FORM_SHOW_TIME);
            }
            let ret = formSetHelper.checkForm(this.fields, this.forms);
            this.setData({
                fieldsClone: this.fields
            });
            if (!ret) {
                return;
            }
            if (this.isConfirm) {
                //是否显示确认信息
                this.setData({
                    showCheckModal: true
                });
            } else {
                this.$emit('submit', {
                    detail: this.forms
                });
            }
        },

        bindSubmitCmpt: function () {
            this.setData({
                showCheckModal: false
            });
            this.$emit('submit', {
                detail: this.forms
            });
        },

        getForms: function () {
            return this.forms;
        }
    },
    created: function () {},
    watch: {
        forms: {
            handler: function (newVal, oldVal) {
                this.formsClone = newVal;
            },

            immediate: true,
            deep: true
        },

        fields: {
            handler: function (newVal, oldVal) {
                this.fieldsClone = newVal;
            },

            immediate: true,
            deep: true
        }
    }
};
</script>
<style>
@import './form_show_cmpt.css';
</style>
